You have been tasked with writing a function to verify that an upload matches its media type.
You do some research and discover that the first few bytes of a file are generally unique to that file type, giving it a sort of signature.
Implement the type_from_extension/1 function. It should take a file extension (string) and return the media type (string) or nil if the extension does not match with the expected ones.
Implement the type_from_binary/1 function. It should take a file (binary) and return the media type (string) or nil if the extension does not match with the expected ones.
Don't worry about reading the file as a binary. Assume that has been done for you and is provided by the tests as an argument.
Implement the verify/2 function. It should take a file (binary) and extension (string) and return an :ok or :error tuple.
https://exercism.org/tracks/elixir/exercises/file-sniffer
defmodule FileSniffer do
@moduledoc """
practice binary
"""
@type_map %{
"exe" => "application/octet-stream",
"bmp" => "image/bmp",
"png" => "image/png",
"jpg" => "image/jpg",
"gif" => "image/gif"
}
def type_from_extension(extension), do: @type_map[extension]
def type_from_binary(file_binary) do
case file_binary do
<<0x7F, 0x45, 0x4C, 0x46, _::binary>> -> "application/octet-stream"
<<0x42, 0x4D, _::binary>> -> "image/bmp"
<<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, _::binary>> -> "image/png"
<<0xFF, 0xD8, 0xFF, _::binary>> -> "image/jpg"
<<0x47, 0x49, 0x46, _::binary>> -> "image/gif"
_ -> nil
end
end
def verify(file_binary, extension) do
type = file_binary |> type_from_binary
if extension |> type_from_extension === type,
do: {:ok, type},
else: {:error, "Warning, file format and file extension do not match."}
end
end